package com.huluobo.jetpackkotlindemo2006a.paging

import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.paging.LoadState
import androidx.recyclerview.widget.LinearLayoutManager
import com.huluobo.jetpackkotlindemo2006a.databinding.ActivityPagingBinding
import com.huluobo.jetpackkotlindemo2006a.viewbinding.BaseActivity
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch

/**
 * Created by lc on 2023/2/22.
 * Paging:是page的进行时,也就是分页加载,之前SmartRefresh进行加载,都是刷新的框架,用于触发页码的刷新
 * 有footer和header来用于加载或者刷新,通过footer加载数据,page++这种情况(如油焖大虾接口)
 * Paging3是google最新推出的分页加载库
 * Paging3总结:
 * 1.Paging最关键的是数据的传递 Repository.getPagingData().cachedIn(viewModelScope) 生成一个数据流,在activity中可以通过
 * viewModel.getPagingData().collect进行接收数据流,).cachedIn(viewModelScope) 可以将请求到的数据流缓存到作用域中,如果当生命周期
 * 发生改变时,可以读取这部分流来进行数据填充,不需要网络加载
 * 2.通过PagingConfig来设置预加载的大小,前后翻页的key
 * 3.通过RepoPagingSource来重写load方法
 * 4.RepoPagingSource才是真正数据源产生的位置,在这当中,触发了网络请求
 * 5.PagingDataAdapter 是配合Paging使用的,构造中需要一个DiffUtil来管理item中数据是否一致
 * 6.LoadStateAdapter 是一个脚布局,主要作用是有个状态LoadState ,通过这个状态可以对应的去写回调
 * 7.Paging给Adapter传递数据的位置 mAdapter.submitData(it) 通过协程Flow从viewModel中拿到数据并填充
 *
 * 8.RemoteMediator 远程调度器 现在的请求都是一个单一数据源,当有网的时候,从网络获取数据
 * 新增需求,无网状态下也需要去获取数据,需要有2个数据源,一个是有网状态,一个是无网状态
 */
class PagingActivity : BaseActivity<ActivityPagingBinding>() {
    override fun getViewBinding(): ActivityPagingBinding =
        ActivityPagingBinding.inflate(layoutInflater)

    //拿到对应的ViewModel,准备数据源
    private val viewModel by lazy {
        ViewModelProvider(this).get(PagingViewModel::class.java)
    }

    //RecycleView的适配器
    private val mAdapter: RepoAdapter = RepoAdapter()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        //设置刷框架的监听器
        mViewBinding.refreshLayout.setOnRefreshListener {
            //当刷新框架刷新时,适配器也跟着刷新
            mAdapter.refresh()
        }

        mViewBinding.recycleView.layoutManager = LinearLayoutManager(this)
        //给适配器添加footer
        mViewBinding.recycleView.adapter = mAdapter.withLoadStateFooter(FooterAdapter {
            //相当于回调,给适配器添加一个对应的重试方法
            mAdapter.retry()
        })

//        //********重点,通过协程发送和接受数据源,给adapter添加数据源
//        lifecycleScope.launch {
//            viewModel.getPagingData().collect {
//                mAdapter.submitData(it)
//            }
//        }


        viewModel.getPagingData2(this).observe(this, {
            mAdapter.submitData(lifecycle, it)
        })

        //adapter的监听状态
        mAdapter.addLoadStateListener {
            when (it.refresh) {
                is LoadState.NotLoading -> {
                    mViewBinding.recycleView.visibility = View.VISIBLE
                    mViewBinding.refreshLayout.isRefreshing = false
                }

                is LoadState.Loading -> {
                    mViewBinding.refreshLayout.isRefreshing = true
                    mViewBinding.recycleView.visibility = View.VISIBLE
                }

                is LoadState.Error -> {
                    val state = it.refresh as LoadState.Error
                    mViewBinding.refreshLayout.isRefreshing = false
                    Toast.makeText(this, "加载失败:${state.error.message}", Toast.LENGTH_SHORT).show()
                }
            }
        }
    }
}